/**
 * Copyright (C) 2012 Dmitriy Kukharev
 *  
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *      http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ru.nsu.weather.data;

import java.util.ArrayList;
import java.util.List;

/**
 * Weather class represents weather snapshot for the last three days.
 * This snapshot is described by start timestamp and stop timestamp which are
 * stored as long values according UTC specification. 
 * @author Dmitriy Kukharev
 *
 */
public class Weather {
	
	/**
	 * Start timestamp
	 */
	private long start;
	
	/**
	 * Stop timestamp 
	 */
	private long stop;
	
	/**
	 * Current temperature for this snapshot
	 */
	private double current;
	
	/**
	 * Average temperature for this snapshot
	 */
	private double average;
	
	/**
	 * List of temperature points which represent exact temperature measurement.
	 * @see Point
	 */
	private List<Point> points;
	
	/**
	 * Default constructor
	 */
	public Weather() {
	}
	
	/**
	 * Create weather snapshot with given parameters
	 * @param start start timestamp
	 * @param stop stop timestamp
	 * @param current current temperature
	 * @param average average temperature for this snapshot
 	 * @param points list of temperature measurement points
	 */
	public Weather(long start, long stop, double current, double average, List<Point> points) {
		this.start = start;
		this.stop = stop;
		this.current = current;
		this.average = average;
		this.points = points;
	}
	
	/**
	 * Returns start timestamp
	 * @return start timestamp
	 */
	public long getStart() {
		return start;
	}
	
	/**
	 * Sets start timestamp
	 * @param start start timestamp
	 */
	public void setStart(long start) {
		this.start = start;
	}
	
	/**
	 * Returns stop timestamp
	 * @return stop timestamp
	 */
	public long getStop() {
		return stop;
	}
	
	/**
	 * Sets stop timestamp
	 * @param stop stop timestamp
	 */
	public void setStop(long stop) {
		this.stop = stop;
	}
	
	/**
	 * Returns current temperature
	 * @return current temperature
	 */
	public double getCurrent() {
		return current;
	}
	
	/**
	 * Sets current temperature
	 * @param current current temperature
	 */
	public void setCurrent(double current) {
		this.current = current;
	}
	
	/**
	 * Returns average temperature
	 * @return average temperature
	 */
	public double getAverage() {
		return average;
	}
	
	/**
	 * Sets average temperature
	 * @param average average temperature
	 */
	public void setAverage(double average) {
		this.average = average;
	}
	
	/**
	 * Returns list of measured temperature points
	 * @return list of measured temperature points
	 * @see Point
	 */
	public List<Point> getPoints() {
		return points;
	}
	
	/**
	 * Sets list of measured temperature points
	 * @param points measured temperature points
	 */
	public void setPoints(List<Point> points) {
		this.points = points;
	}

	/**
	 * Filters current weather snapshot thinning out its points. 
	 * The method creates new weather snapshot without modifying
	 * current one.
	 * @param c number of points which should be skipped while constructing
	 * new snapshot. 
	 * @return new weather snapshot.
	 */
	public Weather filter(int c) {
		
		if (c <= 0)
			return this;
		if (c > 10) 
			c = 10;
		
		List<Point> newPoints = new ArrayList<Weather.Point>();
		int n = points.size();
		for (int i = 0; i < n; i+=c) {
			Point point = points.get(i);
			newPoints.add(new Point(point.timestamp, point.temp));
		}
		return new Weather(start, stop, current, average, newPoints);
	}

	/**
	 * Point class represents measurement of temperature at the given timestamp.
	 * @author Dmitriy Kukharev
	 *
	 */
	public static class Point implements Comparable<Point> {
		/**
		 * timestamp
		 */
		private long timestamp;
		
		/**
		 * temperature
		 */
		private double temp;
		
		/**
		 * Default constructor
		 */
		public Point() {
		}
		
		/**
		 * Create point with given parameters
		 * @param timestamp timestamp of the measurement
		 * @param temp temperature
		 */
		public Point(long timestamp, double temp) {
			this.timestamp = timestamp;
			this.temp = temp;
		}
		
		/**
		 * Returns timestamp of the measurement
		 * @return timestamp of the measurement
		 */
		public long getTimestamp() {
			return timestamp;
		}
		
		/**
		 * Sets timestamp of the measurement
		 * @param timestamp timestamp of the measurement
		 */
		public void setTimestamp(long timestamp) {
			this.timestamp = timestamp;
		}
		
		/**
		 * Returns temperature
		 * @return temperature
		 */
		public double getTemp() {
			return temp;
		}
		
		/**
		 * Sets temperature
		 * @param temp temperature
		 */
		public void setTemp(double temp) {
			this.temp = temp;
		}
		
		@Override
		public int compareTo(Point another) {
			if (timestamp < another.timestamp)
				return -1;
			else if (timestamp > another.timestamp)
				return 1;
			return 0;
		}
	}
}
